1. Field of the Invention
The invention relates to the field of computer systems. More specifically, the invention relates to software debugging.
2. Background Information
Software debugging is the detecting, locating, and correcting of logical and/or syntactical errors in a computer program. Debug hardware is often included in a processor for use by a software debug program. Typically, the debug program uses the debug hardware to allow the programmer to examine data and check conditions during the execution of another computer program. Thus, the debugging features of a processor provide programmers with valuable tools for looking at the dynamic state of the processor.
A typical debug feature, when enabled, reports a debug event in response to a certain condition(s) being meet. The term "event" is used herein to refer to any action or occurrence to which a computer system might respond (e.g., hardware interrupts, software interrupts, exceptions, faults, traps, aborts, machine checks, debug events). Upon recognizing an event, a processor's event handling mechanism causes the processor to interrupt execution of the current process, store the interrupted process' execution environment (i.e., the information necessary to resume execution of the interrupted process), and invokes the appropriate operating system handler. Upon completing the servicing of the event, the invoked handler instructs the processor to resume execution of the interrupted process using the previously stored execution environment. The appropriate handler for debug events is the debug handler. Thus, in response to each debug event, the debug handler is executed. The debug handler is a portion of the debug program and it allows the programmer to perform a variety of debugging techniques. When the programmer is finished, the programmer can cause the debug handler to instruct the processor to resume the interrupted process using the process' previously stored execution environment.
One prior art processor which includes debugging hardware is the Intel.RTM. 80960KB manufactured by Intel Corporation of Santa Clara, Calif. The 80960KB provides for a "branch-trace mode" and an "instruction-trace mode." When the instruction-trace mode is enabled, the processor generates an instruction-trace event each time an instruction is executed. Debug software can use the instruction-trace mode to "single-step" the processor--i.e., interrupt execution after each instruction to allow the debug software to perform various debug techniques. When the branch-trace mode is enabled, the processor generates an branch-trace event each time an instruction that causes a branch (also termed as a "jump") to be taken is executed. An instruction that causes a branch to be taken is one that causes the processor to transfer flow of execution to another instruction (e.g., a jump instruction, a branch instruction, etc..). A taken branch typically transfers the flow of execution in a non-sequential manner--i.e., to an instruction which does not sequentially follow the instruction causing the branch to be taken. A branch-trace event is not generated for conditional-branch instructions that do not result in a branch being taken.
One limitation of this prior art branch-trace mode is that the source address of the branch (i.e., the address identifying the instruction that causes the branch to be taken) is not stored. As a result, this source address is not available for use by the debug handler. One prior art method of capturing the source address of a taken branch is to use the instruction-trace mode in conjunction with the branch-trace mode. According to this method, the instruction-trace mode is used to single step the processor and the address of the previously executed instruction is stored during each instruction-trace event. As a result, when a branch-trace event occurs, the address stored in response to the most recent instruction-trace event is the destination address of the taken branch. However, this method lacks utility in that it greatly degrades performance because the instruction-trace mode causes an event to occur after the execution of every instruction.
Another prior art processor which includes debugging hardware is the Intel Pentium.TM. processor manufactured by Intel Corporation. The Pentium processor provides for a "single-step trap" which is enabled by a TF flag. When enabled, a single-step trap occurs after the execution of the current instruction. Debug software can use the single-step trap to single step the processor. One limitation of this prior art processor is that the INT instructions clear the TF flag. Therefore, software debuggers which single-step code must recognize and emulate INT n or INTO instructions rather than executing them directly. This results in additional overhead when single-stepping. Another limitation of this prior art processor is that additional circuitry had to be included to reconcile the single-step trap with the other events. This circuitry terminates single stepping if an external interrupt occurs. In addition, when both an external interrupt and a single-step interrupt occur together, this circuitry clears the TF flag, saves the return address or switches tasks, and examines the external interrupt input before the first instruction of the single-step handler executes. If the external interrupt is still pending, then it is serviced--i.e., that external interrupt's handler is executed. During the execution of the external interrupt's handler, the single-step trap is disabled. Upon completion of the external interrupt's handler, the processor returns to executing the single-step handler. Thus, operating system routines (such as the external interrupt handlers) are not normally run in single step mode. To run operating system routines in the single step mode, a INTn instruction which calls an interrupt handler must be single stepped. As a result, this processor does not allow single stepping to be enabled on operating system routines as they interact with other programs.
One prior art technique of debugging is "profiling." Profiling is the counting of the number of times each instruction in a routine or program is executed. This count information can be used to determine which sections of code are software performance bottlenecks. These sections of code may then be optimized or restructured to increase performance. The prior art method of profiling uses single-stepping. For example, a prior art profiling program executing on a Pentium processor stores a profiling handler as the debug handler and enables the single-step trap to cause an exception after each instruction. After execution of each instruction, the processor executes the profiling handler which increments a count corresponding to the executed instruction. A limitation of this prior art method is that it greatly degrades performance because an event occurs after the execution of every instruction. This degradation in performance is so severe that use of this method is impractical.